﻿using EntityFramework;
using Microsoft.EntityFrameworkCore;
using NLog;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Expressions;
using System.Text;


namespace Core
{
    /// <summary>
    /// 重构基础方法
    /// </summary>
    public class BaseService : IBaseService
    {
        private readonly Logger Logger = LogManager.GetCurrentClassLogger();

        private readonly MyDbContext _myDbContext;
        public BaseService(MyDbContext myDbContext)
        {
            _myDbContext = myDbContext;
            //Logger.Debug("实例化BaseService");
        }
        /// <summary>
        /// 重构添加操作
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns>1 成功 否则失败</returns>
        public int Insert<T>(T entity) where T : class
        {
            try
            {
                entity= _myDbContext.Set<T>().Add(entity).Entity;
                return _myDbContext.SaveChanges();
            }
            catch (Exception ex)
            {
                return 0;
            }

        }
        /// <summary>
        /// 重构修改方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns>1 成功  否则失败</returns>
        public int Update<T>(T entity) where T : class
        {
            try
            {
                DbSet<T> set = _myDbContext.Set<T>();
                set.Attach(entity);
                _myDbContext.Entry<T>(entity).State = EntityState.Modified;
                return _myDbContext.SaveChanges();
            }
            catch (Exception ex)
            {
                return 0;
            }
        }
        /// <summary>
        /// 重构删除方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <returns>1  成功  否则失败</returns>
        public int Delete<T>(T entity) where T : class
        {
            try
            {

                DbSet<T> set = _myDbContext.Set<T>();
                set.Attach(entity);
                _myDbContext.Entry<T>(entity).State = EntityState.Deleted;
                return _myDbContext.SaveChanges();
            }
            catch (Exception ex)
            {
                return 0;
            }
        }
        /// <summary>
        /// 根据条件删除数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="where"></param>
        /// <returns></returns>
        public int Delete<T>(Expression<Func<T, bool>> where) where T : class
        {
            try
            {
                List<T> list = _myDbContext.Set<T>().Where(where).ToList();
                list.ForEach(item =>
                {
                    _myDbContext.Set<T>().Attach(item);
                    _myDbContext.Set<T>().Remove(item);
                });
                return _myDbContext.SaveChanges();
            }
            catch (Exception ex)
            {
                return 0;
            }
        }
        /// <summary>
        /// 重构判断是否存在该数据方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ID"></param>
        /// <returns>true  成功  false  失败</returns>
        public bool Exists<T>(object ID) where T : class
        {
            try
            {
                T model = _myDbContext.Set<T>().Find(ID);
                if (model != null)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                return false;
            }
        }
        /// <summary>
        /// 重构保存方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="entity"></param>
        /// <param name="ID"></param>
        /// <returns>0  成功  否则失败</returns>
        public int Save<T>(T entity, object ID) where T : class
        {
            int result = 0;
            try
            {
                T model = GetModel<T>(ID);
                if (model != null)
                {
                    result = Update<T>(entity);
                }
                else
                {
                    result = Insert<T>(entity);
                }
            }
            catch (Exception ex)
            {
                result = 0;
            }
            return result;
        }
        /// <summary>
        /// 添加多条
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="dataList"></param>
        /// <returns></returns>
        public int Save<T>(List<T> dataList) where T : class
        {
            try
            {
                dataList.ForEach(item =>
                {
                    _myDbContext.Set<T>().Add(item);
                });
                return _myDbContext.SaveChanges();
            }
            catch (Exception ex)
            {
                return 0;
            }
        }
        /// <summary>
        /// 重构获取单个实体方法
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ID"></param>
        /// <returns>返回实体对象  没有则为 null</returns>
        public T GetModel<T>(object ID) where T : class
        {
            T model = null;
            try
            {

                model = _myDbContext.Set<T>().Find(ID);

            }
            catch (Exception ex)
            {
                model = null;
            }

            return model;
        }
        /// <summary>
        /// 根据条件获取单个实体
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ID"></param>
        /// <param name="where"></param>
        /// <returns></returns>
        public T GetModel<T>(Expression<Func<T, bool>> where, Action<IOrderable<T>> order = null) where T : class
        {
            try
            {
                if (order == null)
                {
                    return _myDbContext.Set<T>().Where(where).FirstOrDefault();
                }
                else
                {
                    var linq = new Orderable<T>(_myDbContext.Set<T>().Where(where));
                    order(linq);
                    return linq.Queryable.FirstOrDefault();
                }
            }
            catch (Exception ex)
            {
                return null;
            }
        }
        /// <summary>
        /// 重构获取集合方法 复杂sql语句
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="table">表名</param>
        /// <param name="strWhere">where条件  sql语句</param>
        /// <returns>返回当前类集合</returns>
        //public List<T> GetList<T>(string table, string strWhere = "") where T : class
        //{
        //    try
        //    {
        //        using (var _myDbContext = _myDbContext)
        //        {
        //            //获取查询语句
        //            string strSql = " select * from " + table + " ";
        //            //查询条件
        //            if (strWhere != "")
        //                strSql += " where " + strWhere;
        //            var bathList = _myDbContext.Database.ExecuteSqlCommand(new RawSqlString(strSql));
        //            return bathList;
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        Logger.Error("BaseDAL:::GetList1" + ex.Message, ex);
        //        return new List<T>();
        //    }
        //}
        /// <summary>
        /// 根据条件获取数据集合
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="where">lamda where条件</param>
        /// <param name="order">lamda 自定义排序</param>
        /// <returns></returns>
        public List<T> GetList<T>(Expression<Func<T, bool>> where, Action<IOrderable<T>> order = null) where T : class
        {
            try
            {
                if (order == null)
                {
                    return _myDbContext.Set<T>().Where(where).ToList();
                }
                else
                {
                    var linq = new Orderable<T>(_myDbContext.Set<T>().Where(where));
                    order(linq);
                    return linq.Queryable.ToList();
                }
            }
            catch (Exception ex)
            {
                return new List<T>();
            }
        }
        /// <summary>
        /// 分页查询
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="PageIndex">当前页</param>
        /// <param name="PageSize">每页条数</param>
        /// <param name="count">返回总行数</param>
        /// <param name="where"></param>
        /// <param name="order"></param>
        /// <returns></returns>
        public List<T> GetList<T>(int PageIndex, int PageSize, ref int count, Expression<Func<T, bool>> where = null, Action<IOrderable<T>> order = null) where T : class
        {
            try
            {
                //排序为空时
                if (order == null)
                {
                    //条件为空时
                    if (where == null)
                    {
                        //返回总条数
                        count = _myDbContext.Set<T>().Count();
                        //返回数据集合
                        return _myDbContext.Set<T>().Skip((PageIndex - 1) * PageSize).Take(PageSize).ToList();
                    }
                    //条件不为空
                    else
                    {
                        count = _myDbContext.Set<T>().Where(where).Count();
                        return _myDbContext.Set<T>().Where(where).Skip((PageIndex - 1) * PageSize).Take(PageSize).ToList();
                    }
                }
                //排序不为空时
                else
                {
                    if (where == null)
                    {
                        var linq = new Orderable<T>(_myDbContext.Set<T>());
                        order(linq);
                        count = linq.Queryable.Count();
                        return linq.Queryable.Skip((PageIndex - 1) * PageSize).Take(PageSize).ToList();
                    }
                    else
                    {
                        var linq = new Orderable<T>(_myDbContext.Set<T>().Where(where));
                        order(linq);
                        count = linq.Queryable.Count();
                        return linq.Queryable.Skip((PageIndex - 1) * PageSize).Take(PageSize).ToList();
                    }
                }
            }
            catch (Exception ex)
            {
                return new List<T>();
            }
        }
        /// <summary>
        /// 根据条件获取个数
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="where"></param>
        /// <returns></returns>
        public int GetCount<T>(Expression<Func<T, bool>> where) where T : class
        {
            int count = 0;
            try
            {
                count = _myDbContext.Set<T>().Where(where).Count();
            }
            catch (Exception ex)
            {
                count = 0;
            }
            return count;
        }
        /// <summary>
        /// 执行sql查询，可接受存储过程
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="sql"></param>
        /// <param name="parmrters"></param>
        /// <returns></returns>
        public DataTable GetSql(string sql, SqlParameter[] parmrters, CommandType type)
        {
            var connection = _myDbContext.Database.GetDbConnection();
            using (var cmd = connection.CreateCommand())
            {
                _myDbContext.Database.OpenConnectionAsync();
                cmd.CommandText = sql;
                cmd.CommandType = type;
                if (parmrters != null && parmrters.Length > 0)
                {
                    cmd.Parameters.AddRange(parmrters);
                }

                //var dr = cmd.ExecuteReader();

                DataTable data = new DataTable();
                using (DbDataReader reader = cmd.ExecuteReader())
                {
                    data.Load(reader);
                }
                _myDbContext.Database.CloseConnection();
                return data;
            }

        }
    }
}
